package com.yifeng.servlet.admin;

import com.yifeng.common.Result;
import com.yifeng.factory.ServiceFactory;
import com.yifeng.model.News;
import com.yifeng.service.NewsService;
import com.yifeng.servlet.BaseServlet;
import com.yifeng.util.AliOssUtil;

import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;

@WebServlet("/admin/news/*")
@MultipartConfig(maxFileSize = 1024 * 1024 * 10)
public class NewsServlet extends BaseServlet {

    /*
    负责人：xiaoq

    功能：通过服务工厂获取 NewsService 实例，用于处理新闻相关的业务逻辑

    参数：无

    返回值:无
    */
    private final NewsService newsService = ServiceFactory.getNewsService();

    /*
    负责人：xiaoq

    功能：统一入口方法，根据 HTTP 请求方法（GET/POST/PUT/DELETE）和路径分发到对应处理逻辑

    参数：req - HTTP 请求对象；resp - HTTP 响应对象

    返回值:无（通过 resp 直接输出 JSON 响应）
    */
    @Override
    protected void doHandle(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String method=req.getMethod().toUpperCase();
        String pathInfo=req.getPathInfo(); //获取/news/*中路径信息

        try {
            switch (method) {
                case "GET":
                    handleGet(req, resp, pathInfo);
                    break;
                case "POST":
                    handlePost(req, resp);
                    break;
                case "PUT":
                    handlePut(req, resp);
                    break;
                case "DELETE":
                    handleDelete(req, resp, pathInfo);
                    break;
                default:
                    writeJson(resp, Result.fail(405,"请求方法错误"+method));
                    break;
            }
        } catch (Exception e){
            writeJson(resp, Result.fail(500,"服务器内部错误"));
        }
    }

    /*
    负责人：xiaoq

    功能：处理 GET 请求，支持按状态分页查询新闻列表（不支持查询单条新闻）

    参数：req - HTTP 请求对象，包含分页参数 page、size 和可选状态 status；resp - HTTP 响应对象；pathInfo - 请求路径信息（如 "/123"）

    返回值:无（通过 resp 输出分页查询结果的 JSON）
    */
//    private void handleGet(HttpServletRequest req, HttpServletResponse resp, String pathInfo) throws IOException {
//        //如果路径包含ID，表示查询新闻详情
//        if(pathInfo!=null && pathInfo.matches("/\\d+")){
//            handleGetById(req,resp,pathInfo);
//            return;
//        }
//
//        //否则是分页查询新闻列表
//        //获取分页参数
//        int pageNum=getIntParameter(req,"page",1);
//        int pageSize=getIntParameter(req,"size",10);
//        String statusParam=req.getParameter("status");
//
//        //校验参数有效性
//        if(pageNum<1 || pageSize<1 || pageSize >100){
//            fail(resp,"分页参数无效");
//            return;
//        }
//        try {
//            Result result;
//            if(statusParam==null || statusParam.trim().isEmpty()){
//                //不指定状态，则查询所有新闻
//                result=newsService.getAllNewsWithPagination(pageNum,pageSize);
//            } else {
//                //指定状态，则按状态查询新闻
//                int status=Integer.parseInt(statusParam);
//                result=newsService.getNewsByStatusWithPagination(status,pageNum,pageSize);
//            }
//        } catch (NumberFormatException e){
//            fail(resp,"状态参数格式错误");
//        } catch (Exception e){
//            fail(resp,"查询新闻列表失败:"+e.getMessage());
//        }
//    }

    //非分页查询
    private void handleGet(HttpServletRequest req, HttpServletResponse resp, String pathInfo) throws IOException {
        //如果路径包含ID，表示查询新闻详情
        if(pathInfo!=null && pathInfo.matches("/\\d+")){
            handleGetById(req,resp,pathInfo);
            return;
        }

        String statusParam=req.getParameter("status");

        try {
            Result result;
            if(statusParam==null || statusParam.trim().isEmpty()){
                //不指定状态，则查询所有新闻
                result=newsService.getAllNews(); //新的 返回所有新闻的方法
            } else {
                //指定状态，则按状态查询新闻
                int status=Integer.parseInt(statusParam);
                result=newsService.getNewsByStatus(status); //新的 按状态查询所有新闻的方法
            }
            writeJson(resp, result);
        } catch (NumberFormatException e){
            writeJson(resp, Result.fail(406,"参数格式错误"));
        } catch (Exception e){
            fail(resp,"查询新闻列表失败:"+e.getMessage());
        }
    }



    /*
    负责人：xiaoq

    功能：处理 POST 请求，用于创建新新闻，从请求体中读取 News 对象并调用服务层保存

    参数：req - HTTP 请求对象，请求体为 JSON 格式的 News 数据；resp - HTTP 响应对象

    返回值:无（通过 resp 返回创建结果的 JSON）
    */
    private void handlePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try{

            /*//从请求体中读取News对象
            News news=readJsonBody(req,News.class);
            if(news==null){
                fail(resp,"请求体不能为空");
                return;
            }

            //基础校验
            if(news.getTitle()==null || news.getTitle().trim().isEmpty()){
                fail(resp,"新闻标题不能为空");
                return;
            }

            if(news.getContent()==null || news.getContent().trim().isEmpty()){
                fail(resp,"新闻内容不能为空");
                return;
            }

            if(news.getCategory()==null || news.getCategory().trim().isEmpty()){
                fail(resp,"新闻类别不能为空");
                return;
            }

            if(news.getAuthor()==null || news.getAuthor().trim().isEmpty()){
                fail(resp,"新闻作者不能为空");
                return;
            }
*/
            News news = new News();
            String title = req.getParameter("title");
            String content = req.getParameter("content");
            String category = req.getParameter("category");
            String author = req.getParameter("author");

            news.setTitle(title);
            news.setContent(content);
            news.setCategory(category);
            news.setAuthor(author);

            //设置默认值
            if(news.getStatus()==null){
                news.setStatus((byte) 0); //默认未发布
            }

            //处理上传图片逻辑
            String contentType = req.getContentType();
            if(contentType != null && contentType.startsWith("multipart/")){
                Part filePart = req.getPart("file");
                // 参数验证
                if (filePart == null || filePart.getSize() == 0) {
                    news.setPicNew(null);
                    Result result=newsService.createNews(news);
                    writeJson(resp,result);
                    return;
                }
                //判断文件是否为图片
                String fileName = filePart.getSubmittedFileName();
                if(fileName != null && (fileName.endsWith(".png") || fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))){
                    String picNew = AliOssUtil.upload(filePart);
                    news.setPicNew(picNew);
                }
            }

            //调用服务层添加新闻
            Result result=newsService.createNews(news);
            writeJson(resp,result);

        } catch(Exception e){
            writeJson(resp, Result.fail(406,"创建新闻失败"));
        }
    }

    /*
    负责人：xiaoq

    功能：处理 PUT 请求，用于更新已有新闻，从请求体读取包含 ID 的 News 对象并调用服务层更新

    参数：req - HTTP 请求对象，请求体为 JSON 格式的 News（需含 newsId）；resp - HTTP 响应对象

    返回值:无（通过 resp 返回更新结果的 JSON）
    */
    private void handlePut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try{
            /*//从请求体中读取News对象
            News news=readJsonBody(req,News.class);
            if(news==null){
                fail(resp,"请求体不能为空");
                return;
            }

            if(news.getNewsId()==null){
                fail(resp,"新闻ID不能为空");
                return;
            }

            if(news.getTitle()==null || news.getTitle().trim().isEmpty()){
                fail(resp,"新闻标题不能为空");
                return;
            }

            if(news.getContent()==null || news.getContent().trim().isEmpty()){
                fail(resp,"新闻内容不能为空");
                return;
            }

            if(news.getCategory()==null || news.getCategory().trim().isEmpty()){
                fail(resp,"新闻类别不能为空");
                return;
            }

            if(news.getAuthor()==null || news.getAuthor().trim().isEmpty()){
                fail(resp,"新闻作者不能为空");
                return;
            }*/

            News news = new News();
            Integer newsId = Integer.parseInt(req.getParameter("newsId"));
            String title = req.getParameter("title");
            String content = req.getParameter("content");
            String category = req.getParameter("category");
            String author = req.getParameter("author");

            if(title == null || title.trim().isEmpty() || content == null ||
                    content.trim().isEmpty() || category == null || category.trim().isEmpty()
                    || author == null || author.trim().isEmpty()){
                writeJson(resp, Result.fail(400,"参数缺失"));
            }

            news.setNewsId(newsId);
            news.setTitle(title);
            news.setContent(content);
            news.setCategory(category);
            news.setAuthor(author);

            //设置默认值
            if(news.getStatus()==null){
                news.setStatus((byte) 0); //默认未发布
            }

            //处理上传图片逻辑
            String contentType = req.getContentType();
            if(contentType != null && contentType.startsWith("multipart/")){
                Part filePart = req.getPart("file");
                // 参数验证
                if (filePart == null || filePart.getSize() == 0) {
                    Result result=newsService.updateNews(news);
                    writeJson(resp,result);
                    return;
                }
                //判断文件是否为图片
                String fileName = filePart.getSubmittedFileName();
                if(fileName != null && (fileName.endsWith(".png") || fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))){
                    String picNew = AliOssUtil.upload(filePart);
                    news.setPicNew(picNew);
                }
            }

            //调用服务层更新新闻
            Result result=newsService.updateNews(news);
            writeJson(resp,result);
        } catch (Exception e){
            writeJson(resp, Result.fail(406,"更新新闻失败"));
        }
    }

    /*
    负责人：xiaoq

    功能：处理 DELETE 请求，根据路径中的新闻 ID 删除指定新闻（如 /news/123）

    参数：req - HTTP 请求对象；resp - HTTP 响应对象；pathInfo - 请求路径信息（如 "/123"）

    返回值:无（通过 resp 返回删除操作结果的 JSON）
    */
    private void handleDelete(HttpServletRequest req, HttpServletResponse resp, String pathInfo) throws IOException {
        if(pathInfo==null || pathInfo.trim().isEmpty() || !pathInfo.matches("/\\d+")){
            writeJson(resp, Result.fail(400,"新闻ID格式错误"));
            return;
        }

        try{
            int newsId=Integer.parseInt(pathInfo.substring(1)); //去掉开头的"/"
            Result result=newsService.deleteNewsById(newsId);
            writeJson(resp,result);
        } catch(NumberFormatException e){
            writeJson(resp, Result.fail(400,"新闻ID格式错误"));
        } catch(Exception e){
            writeJson(resp, Result.fail(406,"删除新闻失败"));
        }
    }




    /*
    负责人：xiaoq

    功能：处理 GET 请求，根据路径中的新闻 ID 查询指定新闻（如 /news/123）

    参数：req - HTTP 请求对象；resp - HTTP 响应对象；pathInfo - 请求路径信息（如 "/123"）

    返回值:无（通过 resp 输出查询结果）
    */
    private void handleGetById(HttpServletRequest req,HttpServletResponse resp,String pathInfo) throws IOException {
        try {
            int newsId=Integer.parseInt(pathInfo.substring(1)); //去掉开头的"/"
            Result result=newsService.getNewsById(newsId);
            writeJson(resp,result);

        } catch(NumberFormatException e) {
            writeJson(resp, Result.fail(400,"新闻ID格式错误"));
        } catch(Exception e){
            writeJson(resp, Result.fail(406,"获取新闻详情失败"));
        }
    }



    /*
    负责人：xiaoq

    功能：从请求参数中获取 int 类型的参数，如未指定则返回默认值

    参数：req - HTTP 请求对象；paramName - 参数名称；defaultValue - 默认值

    返回值:参数值（int 类型）
    */
    private int getIntParameter(HttpServletRequest req,String paramName,int defaultValue){
        String paramValue=req.getParameter(paramName);
        if(paramValue==null || paramValue.trim().isEmpty()){
            return defaultValue;
        }
        try {
            int value=Integer.parseInt(paramValue);
            return value>0 ? value : defaultValue;
        } catch(NumberFormatException e){
            return defaultValue;
        }
    }
}